package site.zhouinfo.server;

import site.zhouinfo.util.AntPathMatcher;

import java.io.File;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 排除检测解析器<br/>
 *
 * @author liudajiang
 * @create_date 2016年7月14日
 */
public class ExcudeScanResolver {
    /**
     * 上次检测结果
     */
    Map<String, Long> lastScanResult;

    /**
     * 排除检测文件列表</br>
     * 缓存已被判定为排除的文件
     */
    Set<File> excudeFile = new HashSet<File>();
    AntPathMatcher matcher = new AntPathMatcher();

    /**
     * 排除检测路径列表
     */
    private List<String> excudePathList = new ArrayList<String>() {
        {
            add("/static/**");
        }
    };

    /**
     * 增加排除路径
     *
     * @param path
     * @create_date 2016年7月14日
     */
    void addExcludePath(String path) {
        excudePathList.add(path);
    }


    /**
     * 是否排除检测该文件
     *
     * @param file
     * @return
     * @create_date 2016年7月14日
     */
    public boolean isExcude(File file) {
        //上次检测记录中有此文件，此文件肯定不是排除文件
        if (lastScanResult.containsKey(file.getAbsolutePath())) {
            return false;
        }
        //查看排除黑名单中是否有此文件
        if (excudeFile.contains(file)) {
            return true;
        }
        if (doJudgeIsExcude(file)) {
            excudeFile.add(file);
            return true;
        }
        return false;
    }

    /**
     * 判断是否该文件排除检测
     *
     * @param file
     * @return
     * @create_date 2016年7月14日
     */
    public boolean doJudgeIsExcude(File file) {
        String filePath = file.getAbsolutePath();
        for (String pattern : excudePathList) {
            if (pattern.startsWith("/") || pattern.startsWith("\\")) {
                pattern = getServerRootPath() + pattern;
            }
            if (File.separator.equals("\\")) {
                pattern = pattern.replace("/", File.separator);
            } else {
                pattern = pattern.replace("\\", File.separator);
            }
            if (matcher.match(pattern, filePath)) {
                return true;
            }
        }
        return false;
    }

    private String getServerRootPath() {
        return AbstarctServer.getRootClassFile().getAbsolutePath();
    }

    public void setLastResult(Map<String, Long> lastResult) {
        this.lastScanResult = lastResult;
    }
}
